<template>
  <div
    id="my-three"
    ref="screenDom"
  ></div>
</template>
<script setup lang="ts">
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { onMounted, onUnmounted, ref, Ref } from 'vue'

let screenDom: Ref<any> = ref(null)
let scene: any = null
let camera: any = null
let renderer: any = null
let control = null
let loader = null
const resize = () => {
  if (scene) {
    clearScene()
  }
  // 1.创建场景
  scene = new THREE.Scene()
  // 2.创建透视投影相机
  camera = new THREE.PerspectiveCamera(50, screenDom.value.clientWidth / screenDom.value.clientHeight, 0.1, 1000)
  // 设置相机位置
  camera.position.set(3, 1, 2)
  // 3.创建WebGLRenderer渲染器
  renderer = new THREE.WebGLRenderer()
  // 通过setSize()方法设置渲染的长宽
  renderer.setSize(screenDom.value.clientWidth, screenDom.value.clientHeight)
  // renderer.setClearColor(0xffffff, 1)
  // 设置渲染位置
  screenDom.value.appendChild(renderer.domElement)

  // 4.创建一个长、宽、高均为5个单位的立方体
  const geometry = new THREE.BoxGeometry(5, 5, 5)

  // 5.创建Lambert网格材质
  const materialBasic = new THREE.MeshLambertMaterial({
    color: 0x00ff00, // 绿色
    wireframe: true, //是否将几何体渲染为线框，默认值为false（即渲染为平面多边形）
  })

  // 6.创建一个网格模型对象
  const mesh = new THREE.Mesh(geometry, materialBasic) //网络模型对象Mesh
  // 把网格模型添加到三维场景
  // scene.add(mesh)
  // 修改几何体位置
  // mesh.position.set(0, 0, 0)

  loader = new GLTFLoader()
  loader.load('static/saber.glb', function (gltf) {
    //将模型添加至场景
    scene.add(gltf.scene)
    //设置模型位置
    gltf.scene.position.set(34, 11, -84)
  })
  // 设置相机看向物体的方向(默认指向三维坐标系的原点)
  camera.lookAt(0, 0, 0)

  // 7.创建光源
  const spotLight1 = new THREE.SpotLight(0xffffff, 2) //(光照颜色, 光照强度)
  // 设置光源位置
  spotLight1.position.set(10, 10, 10)
  const spotLight2 = new THREE.SpotLight(0xffffff, 2) //(光照颜色, 光照强度)
  // 设置光源位置
  spotLight2.position.set(-10, -10, -10)
  // 将光源添加到场景中
  scene.add(spotLight1, spotLight2)

  // 8.为了方便观察3D图像，添加三维坐标系对象
  const axes = new THREE.AxesHelper(8) // 坐标系轴长设置为8
  // 把三维坐标系 添加到场景中
  scene.add(axes)

  // 9.添加控制器
  control = new OrbitControls(camera, renderer.domElement)
  render()
}
const clearScene = () => {
  // cancelAnimationFrame(animationId);
  scene.traverse((child: any) => {
    if (child.material) {
      child.material.dispose()
    }
    if (child.geometry) {
      child.geometry.dispose()
    }
    child = null
  })
  // sceneDomElement.innerHTML = '';
  renderer.forceContextLoss()
  renderer.dispose()
  scene.clear()
  // flows = [];
  scene = null
  camera = null
  control = null
  renderer.domElement = null
  renderer = null
  loader = null
  // sceneDomElement = null;

  let child = screenDom.value.lastElementChild
  while (child) {
    screenDom.value.removeChild(child)
    child = screenDom.value.lastElementChild
  }
  console.log('clearScene')
}
const render = () => {
  //循环调用
  requestAnimationFrame(() => render())
  //渲染
  renderer.render(scene, camera)
}
let timeout: any = null
onUnmounted(() => {
  window.removeEventListener('resize', resize)
})
onMounted(() => {
  window.addEventListener('resize', resize)
  resize()
})
</script>
<style scoped>
#my-three {
  width: 100%;
  height: 100%;
}
</style>
